﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace SimplexEngine
{
    public abstract class Material
    {
        public virtual Boolean IsTransparency { get { return false; } }

        public virtual String TechniqueName { get { return technique_name; } }
        protected String technique_name = "Basic";

        public virtual Effect Effect { get { return effect == null ? null : effect.GetObject<Effect>() ; } }
        protected Resource effect = null;

        public virtual void ApplyParameters(GameTime game_time, Int64 frame_number)
        {
            if (Effect != null)
                OnApplyParameters(game_time, frame_number);
        }

        protected virtual void OnApplyParameters(GameTime game_time, Int64 frame_number)
        {
        }

        protected virtual void ApplyBasicParameters(GameTime game_time, Int64 frame_number)
        {
            Effect.Parameters["World"].SetValue(Root.Instance.RenderSystem.RenderParameters.World);
            Effect.Parameters["View"].SetValue(Root.Instance.RenderSystem.RenderParameters.View);
            Effect.Parameters["Projection"].SetValue(Root.Instance.RenderSystem.RenderParameters.Projection);
        }

        public virtual void ChangeTechnique()
        {
            Effect.CurrentTechnique = Effect.Techniques[technique_name];
        }

        public abstract Material Clone();

        public virtual String Name { get { return "Material"; } }

        public virtual void SetParameters(Dictionary<String, Object> parameters) { }

        public virtual Dictionary<String, Object> GetParameters() { return new Dictionary<String, Object>(); }

        public virtual Boolean CanInstancing { get { return false; } }
    }

    public class MaterialTexture
    {
        public void Create(String texture_name, Boolean is_texture_dynamic)
        {
            is_dynamic = is_texture_dynamic;
            if (is_dynamic)
            {
                String[] names = texture_name.Split(":".ToCharArray());
                dynamic_texture = Root.Instance.RenderSystem.GetRenderContext(names[0]);
                dynamic_texture_name = names[1];
            }
            else
                texture = Root.Instance.ContentSystem.GetResource(texture_name);
        }

        public Texture2D Texture 
        { 
            get 
            {
                return is_dynamic ? (dynamic_texture == null ? null : dynamic_texture.GetTexture(dynamic_texture_name)) : (texture == null ? null : texture.GetObject<Texture2D>()); 
            } 
        }

        protected Boolean is_dynamic = false;
        protected Resource texture = null;
        protected RenderContext dynamic_texture = null;
        protected String dynamic_texture_name = "";

    }

    public abstract class MaterialFactory
    {
        public abstract String Name { get; }

        public abstract Material CreateMaterial();
    }
}
